package com.ruan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruan.common.Code;
import com.ruan.common.Result;
import com.ruan.mapper.*;
import com.ruan.pojo.*;
import com.ruan.service.OnDutyService;
import com.ruan.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Date;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class OnDutyServiceImpl extends ServiceImpl<OnDutyMapper, OnDuty> implements OnDutyService {

    @Autowired
    private DepartLocationMapper departLocationMapper;

    @Autowired
    private OnDutyMapper onDutyMapper;

    @Autowired
    private OnDutySetMapper onDutySetMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

//    /**
//     * 分页条件查询上月份的出勤数据列表
//     * @param currentPage 当前页
//     * @param pageSize 每页最大数
//     * @param ltoQueryCondition 查询条件
//     * @return
//     */
//    @Override
//    public Result selectOnDutyDTO(int currentPage,
//                                  int pageSize,
//                                  LTOQueryCondition ltoQueryCondition) {
//        System.out.println("selectOnDutyDTO的参数是"+ltoQueryCondition);
//        Date month = ltoQueryCondition.getMonth();//2024-2-1
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-01");
//        String firstDay = sdf.format(month);
////        System.out.println("第一天------"+firstDay);
//        String lastDay = DateUtils.getLastDay(firstDay);//每月最后一天
//
//        LambdaQueryWrapper<OnDuty> queryWrapper =new LambdaQueryWrapper<>();
//        //----------------------------------------------------
//        LambdaQueryWrapper<Employee> queryWrapper1 =new LambdaQueryWrapper<>();
//        queryWrapper1.like(Employee::getName,ltoQueryCondition.getName());
//        List<Employee> employeeList = employeeMapper.selectList(queryWrapper1);
//        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
////        wrapper.in("employee_id", employeeIds);//是QueryWrapper的技术语句
//        queryWrapper.in(OnDuty::getEmployeeId, employeeIds);
////        for (Employee employee : employeeList) {
////            // 在这里处理每个部门对象
////            queryWrapper.eq(ltoQueryCondition.getName()!=null,OnDuty::getEmployeeId,employee.getId());
////        }
//        queryWrapper.eq(ltoQueryCondition.getDepartmentId()!=null,OnDuty::getDepartmentId,ltoQueryCondition.getDepartmentId());
////        queryWrapper.like(ltoQueryCondition.getName()!=null,OnDuty::getName,ltoQueryCondition.getName());
//        queryWrapper.between(OnDuty::getDay,firstDay,lastDay);
//        queryWrapper.groupBy(OnDuty::getEmployeeId);
////        queryWrapper.groupBy(OnDuty::getPhone);
//
//        Page<OnDuty> iPage = new Page<>(currentPage,pageSize);
//        onDutyMapper.selectPage(iPage, queryWrapper);
////        System.out.println("total-->>>"+iPage.getTotal());
//        List<OnDuty> onDuties = iPage.getRecords();
////        System.out.println("onDuties->>>>>>"+onDuties);
//        List<OnDutyDTO> onDutyDTOList = new ArrayList<>();
//        for (OnDuty onDuty : onDuties) {
//            OnDutyDTO onDutyDTO = new OnDutyDTO();
//            System.out.println("onDuty是："+onDuty);
//            Long employeeId = onDuty.getEmployeeId();
//            List<String> status = onDutyMapper.selectStatus(employeeId,firstDay,lastDay);
////---------------------------------------------------
////            QueryWrapper<OnDuty> Wrapper = new QueryWrapper<>();
////            Wrapper.select("status")
////                    .eq("employeeId", onDuty.getEmployeeId())
////                    .between("day", firstDay, lastDay);
////            List<String> status = onDutyMapper.select(Wrapper);
//
////            List<String> status = onDutyMapper.selectStatus(onDuty.getPhone(),firstDay,lastDay);
//                System.out.println("status是：" + status);
//                onDutyDTO.setStatus(status);
//
//            onDutyDTO.setTotal(iPage.getTotal());
//            BeanUtils.copyProperties(onDuty,onDutyDTO);
//            onDutyDTOList.add(onDutyDTO);
//        }
////        System.out.println(onDutyDTOList);
//        return new Result(Code.SELECT_OK,iPageExt);
////        return onDutyDTOList;
//    }

    /**
     * 获取出差记录的status，判断是否打卡
     * @param phone 员工手机号
     * @return
     */
    @Override
    public Result getOnDutyStatus(String phone) {

        LambdaQueryWrapper<OnDuty> queryWrapper = new LambdaQueryWrapper<>();
        //-----------------------------------
        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Employee::getPhone,phone);
        Employee employee = employeeMapper.selectOne(queryWrapper1);

        queryWrapper.eq(OnDuty::getEmployeeId,employee.getId());

        Date date = new Date(System.currentTimeMillis());
        queryWrapper.eq(OnDuty::getDay,date);
        OnDuty onDuty = onDutyMapper.selectOne(queryWrapper);
        if (onDuty == null){
            return new Result(Code.ONDUTY_ERR,"今天还未打卡,请及时打卡！");
        }else {

            LambdaQueryWrapper<OnDuty> queryWrapperQuery = new LambdaQueryWrapper<>();
            Date day = new Date(System.currentTimeMillis());

            queryWrapperQuery.eq(OnDuty::getEmployeeId,employee.getId());

            queryWrapperQuery.eq(OnDuty::getDay,day);
            OnDuty onDuty1 = onDutyMapper.selectOne(queryWrapperQuery);
//            System.out.println("onDuty1是"+onDuty1);
            if (onDuty1!=null && !onDuty1.getStatus().isEmpty()){
                if (onDuty1.getStatus().equals("请假")){
                    return new Result(Code.ONDUTY_ERR,"今天已请假，无须打卡！");
                }
                if (onDuty1.getStatus().equals("出差")){
                    return new Result(Code.ONDUTY_ERR,"今天已出差，无须打卡！");
                }
                if (onDuty1.getStatus().equals("休息")){
                    return new Result(Code.ONDUTY_ERR,"今天休息，无须打卡！");
                }
            }

            //如果不等于null，肯定完成了上班打卡
            Time leaveTime = onDuty.getLeaveTime();
            if (leaveTime!=null){
                return new Result(Code.ONDUTY_START_END_OK,"今天已完成全部打卡！");
            }else {
                return new Result(Code.ONDUTY_END_ERR,"今天已完成上班打卡，未下班打卡！");
            }

        }
    }


    /**
     * 员工打卡上班，新增出勤记录
     * @param requestBody(location,onDuty) 出勤记录
     * @return
     */
    @Override
    public Result punchIn(PunchInRequestBody requestBody) {
        System.out.println("punchIn传的什么参数："+requestBody);
        Location location = requestBody.getLocation();
        OnDuty onDuty = requestBody.getOnDuty();

        LambdaQueryWrapper<OnDuty> queryWrapper = new LambdaQueryWrapper<>();
        Long employeeId = onDuty.getEmployeeId();

        //使用 System.currentTimeMillis() 方法获取当前系统时间的毫秒数，
        // 并将其传递给 Date 构造函数，从而创建了一个代表当前时间的 Date 对象。
        Date day = new Date(System.currentTimeMillis());

        queryWrapper.eq(OnDuty::getEmployeeId,employeeId);
        queryWrapper.eq(OnDuty::getDay,day);
        OnDuty onDuty1 = onDutyMapper.selectOne(queryWrapper);
        if (onDuty1!=null && !onDuty1.getStatus().isEmpty()){
            if (onDuty1.getStatus().equals("请假")){
                return new Result(Code.ONDUTY_ERR,"今日已请假，无须打卡！");
            }
            if (onDuty1.getStatus().equals("出差")){
                return new Result(Code.ONDUTY_ERR,"今日已出差，无须打卡！");
            }
            if (onDuty1.getStatus().equals("休息")){
                return new Result(Code.ONDUTY_ERR,"今日休息，无须打卡！");
            }
        }
//获取数据库中的上班设置信息(上班时间)。
        OnDutySet onDutySet = onDutySetMapper.selectById(1);
        //从获取的上班设置信息中取得上班时间 startTime
        Time startTime = onDutySet.getStartTime();
        //获取当前时间
        Time nowTime = new Time(System.currentTimeMillis());
        //设置员工的到岗时间为当前时间 nowTime
        onDuty.setArriveTime(nowTime);
        //设置员工的工作日期
        onDuty.setDay(day);
        //将当前时间和上班时间转换为字符串，并使用冒号":"进行分割，后转换为整数，方便后续比较。
        String[] nowTimeStrings = nowTime.toString().split(":");
        //将时、分、秒拼接成一个不带分隔符的字符串，存储在nowTimeStr中。
        String nowTimeStr = nowTimeStrings[0]+nowTimeStrings[1]+nowTimeStrings[2];
        //转换为整数
        int nowTimeInt = Integer.parseInt(nowTimeStr);

        String[] startTimeStrings = startTime.toString().split(":");
        String startTimeStr = startTimeStrings[0]+startTimeStrings[1]+startTimeStrings[2];
        int startTimeInt = Integer.parseInt(startTimeStr);
        //将上班时间延后1秒的时间计算出来，用于判断是否迟到
        int startTimeTenAfter = startTimeInt +1000;//1秒缓冲时间

        if (nowTimeInt > startTimeTenAfter ){
            onDuty.setStatus("迟到");
        }
        // 公司设定的签到地点坐标范围
        Long departId = onDuty.getDepartmentId();
       LambdaQueryWrapper<DepartLocation> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(DepartLocation::getDepartmentId,departId);
        DepartLocation departLocation = departLocationMapper.selectOne(queryWrapper1);
        if(departLocation!=null){
            String companyLatitudeString = departLocation.getLatitude();
            String companyLongitudeString = departLocation.getLongitude();
            Double companyLatitude = Double.parseDouble(companyLatitudeString);
            Double companyLongitude = Double.parseDouble(companyLongitudeString);
        double radius = 10; // 公司签到范围半径

// 假设location.getLatitude()返回经度值的字符串
        String latitudeString = location.getLatitude();
        String longitudeString = location.getLongitude();
// 使用Double.parseDouble()方法将字符串转换为double类型
        double latitudeDouble = Double.parseDouble(latitudeString);
        double longitudeDouble = Double.parseDouble(longitudeString);
// 现在latitudeDouble就是double类型的经度值
        System.out.println("当前经度："+latitudeDouble+"当前纬度: "+longitudeDouble);
        //勾股定理
        double distance = Math.sqrt(Math.pow(latitudeDouble -
                companyLatitude, 2) + Math.pow(longitudeDouble -
                companyLongitude, 2));

        // 计算员工位置与公司位置的距离
//        double distance = Math.sqrt(Math.pow(location.getLatitude() -
//                companyLatitude, 2) + Math.pow(location.getLongitude() -
//                companyLongitude, 2));

//        if (distance <= radius) {
//            return new Result(Code.ONDUTY_START_OK,"上班打卡成功！");
//        } else {
//            return new Result(Code.ONDUTY_START_ERR,"上班打卡失败！");
//        }
        try {
            System.out.println("定位在公司范围内吗"+distance+"对比"+radius);
            if (distance <= radius) {
                onDutyMapper.insert(onDuty);
                return new Result(Code.ONDUTY_START_OK, "上班打卡成功！");
            } else {
                return new Result(Code.ONDUTY_START_ERR,"当前的定位不正确，上班打卡失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.ONDUTY_START_ERR,"上班打卡失败！");
        }
     }
        return new Result(Code.ONDUTY_START_ERR,"定位获取失败，你所在的部门可能还没添加定位!");
    }


    //员工打卡下班
    //员工手机号
    @Override
    public Result punchOut(String phone,Location location) {
        System.out.println("punchOut传的是："+location+phone);
        LambdaQueryWrapper<OnDuty> queryWrapperQuery = new LambdaQueryWrapper<>();
        Date day = new Date(System.currentTimeMillis());

        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Employee::getPhone,phone);
        Employee employee = employeeMapper.selectOne(queryWrapper1);

        queryWrapperQuery.eq(OnDuty::getEmployeeId,employee.getId());
        queryWrapperQuery.eq(OnDuty::getDay,day);
        //断网状态下上班打卡，可能会生成多条出勤记录
        OnDuty onDuty1 = onDutyMapper.selectOne(queryWrapperQuery);
        if (onDuty1!=null && !onDuty1.getStatus().isEmpty()){
            if (onDuty1.getStatus().equals("请假")){
                return new Result(Code.ONDUTY_ERR,"今日已请假，无须打卡！");
            }
            if (onDuty1.getStatus().equals("出差")){
                return new Result(Code.ONDUTY_ERR,"今日已出差，无须打卡！");
            }
            if (onDuty1.getStatus().equals("休息")){
                return new Result(Code.ONDUTY_ERR,"今日休息，无须打卡！");
            }
        }

        LambdaQueryWrapper<OnDuty> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OnDuty::getEmployeeId,employee.getId());
        queryWrapper.eq(OnDuty::getDay,day);
        OnDuty onDuty = onDutyMapper.selectOne(queryWrapper);

        OnDutySet onDutySet = onDutySetMapper.selectById(1);
        Time endTime = onDutySet.getEndTime();
        Time nowTime = new Time(System.currentTimeMillis());

        String[] nowTimeStrings = nowTime.toString().split(":");
        String nowTimeStr = nowTimeStrings[0]+nowTimeStrings[1]+nowTimeStrings[2];
        int nowTimeInt = Integer.parseInt(nowTimeStr);

        String[] endTimeStrings = endTime.toString().split(":");
        String endTimeStr = endTimeStrings[0]+endTimeStrings[1]+endTimeStrings[2];
        int endTimeStrInt = Integer.parseInt(endTimeStr);

        if (onDuty == null){//能否查到该用户的onDuty()当天打卡上班的记录
            return new Result(Code.ONDUTY_END_ERR,"请先上班打卡！");
        }else {
            // 公司设定的签到地点坐标范围
            Long departId = onDuty.getDepartmentId();
//            DepartLocation departLocation = departLocationMapper.selectById(departId);
            LambdaQueryWrapper<DepartLocation> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(DepartLocation::getDepartmentId, departId);
            DepartLocation departLocation = departLocationMapper.selectOne(queryWrapper2);
            if (departLocation != null) {
                String companyLatitudeString = departLocation.getLatitude();
                String companyLongitudeString = departLocation.getLongitude();

                Double companyLatitude = Double.parseDouble(companyLatitudeString);
                Double companyLongitude = Double.parseDouble(companyLongitudeString);

//        double companyLatitude = 22.837324;
//        double companyLongitude = 113.504272;
                double radius = 10; // 公司签到范围半径

// 假设location.getLatitude()返回经度值的字符串
                String latitudeString = location.getLatitude();
                String longitudeString = location.getLongitude();
// 使用Double.parseDouble()方法将字符串转换为double类型
                double latitudeDouble = Double.parseDouble(latitudeString);
                double longitudeDouble = Double.parseDouble(longitudeString);
// 现在latitudeDouble就是double类型的经度值
                System.out.println("当前经度：" + latitudeDouble + "当前纬度: " + longitudeDouble);
                double distance = Math.sqrt(Math.pow(latitudeDouble -
                        companyLatitude, 2) + Math.pow(longitudeDouble -
                        companyLongitude, 2));

                onDuty.setLeaveTime(nowTime);
                if (nowTimeInt < endTimeStrInt) {
                    if (!onDuty.getStatus().equals("迟到")) {
                        onDuty.setStatus("早退");
                    }
                }
                if (nowTimeInt > endTimeStrInt) {
                    if (onDuty.getStatus() == null) {
                        onDuty.setStatus("正常");
                    }
                }

                System.out.println("定位在公司范围内吗" + distance + "对比" + radius);
                if (distance <= radius) {
                    onDutyMapper.updateById(onDuty);
                    return new Result(Code.ONDUTY_END_OK, "下班打卡成功！");
                } else {
                    return new Result(Code.ONDUTY_START_ERR, "当前的定位不正确，下班打卡失败！");
                }
          }
//            onDutyMapper.updateById(onDuty);
//            return new Result(Code.ONDUTY_END_OK,"下班打卡成功！");
            }
        return new Result(Code.ONDUTY_START_ERR, "你所在的部门还没有添加定位！");

    }


    //分页+条件 获取个人出勤记录
    //currentPage 当前页pageSize 每页最大数
    @Override
    public IPage<OnDuty> getSelfOnDuty(int currentPage,
                                       int pageSize,
                                       QuerySelfAttendanceCondition querySelfAttendanceCondition) {
        Date month = querySelfAttendanceCondition.getMonth();//2024-2-1
        IPage<OnDuty> iPage=new Page<>(currentPage,pageSize);
        QueryWrapper<OnDuty> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(querySelfAttendanceCondition.getStatus()!=null,
                "status", querySelfAttendanceCondition.getStatus());

        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Employee::getPhone,querySelfAttendanceCondition.getPhone());
        Employee employee = employeeMapper.selectOne(queryWrapper1);
        queryWrapper.eq("employee_id", employee.getId());

        if (month!=null){
            String firstDay = month.toString();//每月的第一天
            String lastDay = DateUtils.getLastDay(firstDay);//每月最后一天

            queryWrapper.between("day",firstDay,lastDay);
            queryWrapper.orderByDesc("day");//生效了？？
            return onDutyMapper.selectPage(iPage,queryWrapper);
        }else {
            queryWrapper.orderByDesc("day");//不生效？？
            return onDutyMapper.selectPage(iPage,queryWrapper);
        }

    }

    @Override
    public Result setOnDutyStatus(String phone, String day, String status) {

        LambdaQueryWrapper<OnDuty> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OnDuty::getDay,day);
        //--------------------------------
        LambdaQueryWrapper<Employee> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Employee::getPhone,phone);
        Employee employee = employeeMapper.selectOne(queryWrapper1);

        queryWrapper.eq(OnDuty::getEmployeeId,employee.getId());
//        queryWrapper.eq(OnDuty::getPhone,phone);
        try {
            OnDuty onDuty = onDutyMapper.selectOne(queryWrapper);
            onDuty.setStatus(status);
            onDutyMapper.updateById(onDuty);
            return new Result(Code.UPDATE_OK,"更新出勤状态成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(Code.UPDATE_ERR,"更新出勤状态失败！");
        }


    }


}
